package pub.wkq.mq;

import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * 构建发布订阅模式的生产者发送消息
 */
public class PubSubProducer {
    public static void main(String[] args) throws IOException, TimeoutException {
        //1. 创建连接工厂以及相关的参数配置
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("43.136.173.173");
        factory.setPort(5672);
        factory.setVirtualHost("hire");
        factory.setUsername("hire");
        factory.setPassword("hire");
        //2. 通过工厂创建连接
        Connection connection = factory.newConnection();
        //3. 通过连接创建通道
        Channel channel = connection.createChannel();
        //4. 创建交换机 Exchange
        /**
         * exchange: 交换机名称
         * type: 交换机类型，
         *      fanout：广播类型(发布订阅)，所有绑定到交换机的队列都可以接收消息,
         *      direct：定向类型，通过 routingKey 和交换机绑定的队列可以接收消息
         *      topic：通配符类型，通过 routingKey 和交换机绑定的队列可以接收消息 ，基于 direct 的基础上增加了通配符匹配
         *      headers：headers 类型，通过 headers 和交换机绑定的队列可以接收消息 ，不常用
         * durable：是否持久化，true表示持久化，false表示不持久化，重启后交换机是否存在
         * internal: 是否内置，true：表示是内置的交换机，客户端程序无法直接发送消息到这个交换机中，只能通过交换机路由到交换机的方式.用户创建的队列不会消费该类型交换机下的消息，所以一般使用 false 即可
         * autoDelete: 是否自动删除，true：消费者断开连接后，交换机是否自动删除，一般设置为 false
         * arguments: 额外参数,map
         */
        String exchangeName = "exchange";
        channel.exchangeDeclare(exchangeName, BuiltinExchangeType.FANOUT, true, false, false, null);
        //5. 定义两个队列
        String fanout_queue_a = "fanout_queue_a";
        String fanout_queue_b = "fanout_queue_b";
        channel.queueDeclare(fanout_queue_a, true, false, false, null);
        channel.queueDeclare(fanout_queue_b, true, false, false, null);
        //6. 将队列绑定到交换机上
        channel.queueBind(fanout_queue_a, exchangeName, "");
        channel.queueBind(fanout_queue_b, exchangeName, "");
        //7. 向队列发送消息
        /**
         * exchange: 交换机名称，简单模式下使用默认的交换机，名称为空即可
         * routingKey: 路由键，简单模式下使用队列名称
         * props: 额外参数
         * body: 消息内容
         */
        for (int i = 0; i < 10; i++) {
            String message = "pubsub" + i;
            channel.basicPublish(exchangeName, "", null, message.getBytes());
        }
//        channel.basicPublish("","hello",null,message.getBytes());
        //6. 释放资源
        channel.close();
        connection.close();

    }
}
